package khai.tomcat.http;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 启动:
 * 解析tomcat.xml
 * 初始化servlet，映射url
 * 服务端监听
 * <p>
 * 请求:
 * 解析协议 转换成 Request Response
 * 映射请求 到 servlet
 * Response 流写入数据
 */
public class TomcatStart {
    private final static int port = 80;

    private Map<String, Servlet> urlMap = new LinkedHashMap<>();

    public TomcatStart() throws Exception {
        readXml();
        server();
    }

    private void readXml() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Document doc;
        try {
            doc = new SAXReader().read("L:\\public\\bold\\spring\\src\\main\\webapp\\WEB-INF\\tomcat.xml");
        } catch (DocumentException e) {
            throw new RuntimeException("请检查xml配置");
        }
        if (doc != null) {
            Element root = doc.getRootElement();//web
            for (Iterator i = root.elementIterator(); i.hasNext(); ) {//servlet
                Element element = (Element) i.next();

                String url = "";
                Servlet object = null;
                for (Iterator nextI = element.elementIterator(); nextI.hasNext(); ) {
                    Element el = (Element) nextI.next();
                    if ("class".equals(el.getName())) {
                        String className = el.getText();
                        Class c = this.getClass().getClassLoader().loadClass(className);
                        object = (Servlet) c.newInstance();
                    } else if ("url".equals(el.getName())) {
                        url = el.getText();
                    }
                }
                urlMap.put(url, object);

            }
        }
    }

    private void server() throws IOException {
        ServerSocket serverSocket = new ServerSocket(port);

        while (true) {
            Socket socket = serverSocket.accept();
            InputStream is = socket.getInputStream();
            OutputStream out = socket.getOutputStream();
            try {

                out.write("success".getBytes());
                Request request = new Request(is);
                Response response = new Response(out);

                String uri = request.getUri();
                for (Map.Entry<String, Servlet> entry : urlMap.entrySet()) {
                    if (uri.startsWith(entry.getKey())) {
                        entry.getValue().service(request, response);
                        break;
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                is.close();
                out.close();
                socket.close();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        new TomcatStart();
    }

}
